package com.splant.android.smart.UILevel.widget;

import android.app.Activity;
import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.splant.android.smart.ModelLevel.DetectorListBean;
import com.splant.android.smart.ModelLevel.DetectorMapObject;
import com.splant.android.smart.ModelLevel.MapImage;
import com.splant.android.smart.ModelLevel.WaterListBean;
import com.splant.android.smart.ModelLevel.WaterMapObject;
import com.splant.android.smart.SystemDefinedLevel.Utils.System_Dimen_Util;
import java.util.ArrayList;
import java.util.List;

public class MapViewLayout extends FrameLayout {

    private MapImage mapImage;
    private List<View> viewList;

    public MapViewLayout(@NonNull Context context) {
        this(context, null);
    }

    public MapViewLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MapViewLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {

        super(context, attrs, defStyleAttr);
        //第二步：创建存放View的集合
        viewList = new ArrayList<>();
        mapImage = new MapImage();

    }

    private float lengthOld = 1;//初始化两指之间原长
    private int preX, preY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //多指触控
        //获取事件源，并通过event.getActionMasked()加入多点触控支持
        switch (event.getAction() & event.getActionMasked()) {

            case MotionEvent.ACTION_DOWN:
                preX = (int) event.getX();
                preY = (int) event.getY();
                //单指移动
                operMode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                //多指缩放
                operMode = SCALE;
                //计算两指间开始的原长
                lengthOld = calculation(event);
               // cancelOnClick();
                break;
            case MotionEvent.ACTION_UP:
                lengthOld = 1;//复位
                operMode = 0;
               // setOnClick();
                break;
            case MotionEvent.ACTION_MOVE:
                int mx = (int) event.getX();
                int my = (int) event.getY();

                if (operMode == DRAG)
                {
                    int newLeft = mx - preX + mapImage.getLeft();
                    int newTop = my - preY + mapImage.getTop();

                    Log.i("Map","newLeft:"+newLeft+"newTop:"+newTop);

                    Log.i("Map", "minleft:" + mapImage.getMinLeft() +"maxLeft:" + mapImage.getMaxLeft() +  " mintop:" + mapImage.getMinTop() + "maxTop:" + mapImage.getMaxTop());

                    if (mapImage.getMinLeft() != mapImage.getMaxLeft() && mapImage.getMinTop() == mapImage.getMaxTop()) {

                        if (newLeft <= mapImage.getMinLeft() || newLeft >= mapImage.getMaxLeft())
                            break;
                        mapImage.setLeft(newLeft);

                    } else if (mapImage.getMinLeft() == mapImage.getMaxLeft() && mapImage.getMinTop() != mapImage.getMaxTop()) {

                        if (newTop <= mapImage.getMinTop() || newTop >= mapImage.getMaxTop())
                            break;
                        mapImage.setTop(newTop);

                    } else {

                        if (newLeft<mapImage.getMinLeft())
                            newLeft=mapImage.getMinLeft();

                        if (newLeft>mapImage.getMaxLeft())
                            newLeft=mapImage.getMaxLeft();

                        if (newTop<mapImage.getMinTop())
                            newTop=mapImage.getMinTop();

                        if (newTop>mapImage.getMaxTop())
                            newTop=mapImage.getMaxTop();

                        mapImage.setLeft(newLeft);
                        mapImage.setTop(newTop);
                    }
                    mapImage.showNewState();
                    preX = mx;
                    preY = my;

                    updateDeviceViewStation();

                } else if (operMode == SCALE) {

                    float scale = calculation(event) / lengthOld;
                    float ls = (float) 0.97;

                    if (scale > 1)
                        ls = (float) 1.03;

                    scaleMap(scale, ls);
                }
                break;
        }
        return true;
    }

    public void zoomMap(boolean b) {

        float scale =  0.6f;
        float ls =  0.6f;
        if (b) {
            scale = 1.4f;
            ls = 1.4f;
        }
        scaleMap(scale, ls);
    }

    private void scaleMap(float scale, float ls) {

        //两指缩放，要计算缩放比例
        int newMapWidth = 0;
        int newMapHeight = 0;

        if (scale < 1) {

            newMapWidth = (int) (mapImage.getWidth() * ls);
            newMapHeight = (int) (newMapWidth * mapImage.getHwScale());

            //Log.i("Map", "缩小");
            if (mapImage.getWidth() >= mapImage.getHeight()) {
               // Log.i("Map", "mapViewWidth" + mapViewWidth);

                if (mapImage.getWidth() == mapViewWidth) {
                   // Log.i("Map", "缩到最小了 left:" + mapImage.getLeft() + " top:" + mapImage.getTop() + " mapWidth:" + mapImage.getImageMap().getWidth() + "mapHeight:" + mapImage.getImageMap().getHeight());
                    return;
                } else {
                    if (newMapWidth < mapViewWidth) {
                        newMapWidth = mapViewWidth;
                        newMapHeight = (int) (newMapWidth * mapImage.getHwScale());
                    }
                }


            } else {

                if (mapImage.getHeight() == mapViewHeight) {
                  //  Log.i("Map", "缩到最小了 left:" + mapImage.getLeft() + " top:" + mapImage.getTop() + " mapWidth:" + mapImage.getImageMap().getWidth() + "mapHeight:" + mapImage.getImageMap().getHeight());
                    return;
                } else {
                    if (newMapHeight < mapViewHeight) {
                        newMapHeight = mapViewHeight;
                        newMapWidth = (int) (newMapHeight * mapImage.getWhScale());
                    }
                }

            }
        } else {

            newMapWidth = (int) (mapImage.getWidth() * ls);
            newMapHeight = (int) (newMapWidth * mapImage.getHwScale());

//            Log.i("Map", "放大");
            int maxMapWidth = mapViewWidth * 5;
            if (mapImage.getWidth() == maxMapWidth) {
//                Log.i("Map", "放到最大了");
                return;
            } else {
                if (newMapWidth > maxMapWidth) {
                    newMapWidth = maxMapWidth;
                    newMapHeight = (int) (newMapWidth * mapImage.getHwScale());
                }
            }
        }

        mapImage.setWidth(newMapWidth);
        mapImage.setHeight(newMapHeight);

//        mapImage.setLeft((mapViewWidth - mapImage.getWidth()) / 2);
//        mapImage.setTop((mapViewHeight - mapImage.getHeight()) / 2);

        int ml = mapViewWidth - mapImage.getWidth();

        if (ml < 0) {
            mapImage.setMinLeft(ml);
            mapImage.setMaxLeft(0);
        } else {
            mapImage.setMinLeft(ml);
            mapImage.setMaxLeft(ml);
        }

        int mt = mapViewHeight - mapImage.getHeight();
        if (mt < 0) {
            mapImage.setMinTop(mt);
            mapImage.setMaxTop(0);
        } else {
            mapImage.setMinTop(mt);
            mapImage.setMaxTop(mt);
        }

        Log.i("Map","HwScale:"+mapImage.getHwScale()+" WhScale:"+mapImage.getWhScale());

        Log.i("Map", "left:" + mapImage.getLeft() + " top:" + mapImage.getTop() + " mapWidth:" + mapImage.getImageMap().getWidth() + "mapHeight:" + mapImage.getImageMap().getHeight());

        Log.i("Map", "minleft:" + mapImage.getMinLeft() +"maxLeft:" + mapImage.getMaxLeft() +  " mintop:" + mapImage.getMinTop() + "maxTop:" + mapImage.getMaxTop());

        mapImage.showNewState();

        updateDeviceViewStation();
    }

    private float calculation(MotionEvent event) {

        if (event.getPointerCount() > 1) {
            float x1 = event.getX();
            float x2 = event.getX(1);
            float y1 = event.getY();
            float y2 = event.getY(1);

            return (float) Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
        } else
            return 1;

    }

    private int mapViewWidth, mapViewHeight;//视图宽度和高度
    private int operMode;//用户操作模式
    private final int DRAG = 1;
    private final int SCALE = 2;

    private Activity activity;

    public void initMap(Activity activity, ImageView img_map, int mapImgWidth, int mapImgHeight, int mapViewWidth, int mapViewHeight) {

        this.activity = activity;
        this.mapViewWidth = mapViewWidth;
        this.mapViewHeight = mapViewHeight;

        setMapInitSize(img_map, mapImgWidth, mapImgHeight);
    }

    private void setMapInitSize(ImageView img_map, int mapImgWidth, int mapImgHeight) {

        mapImage.setImageMap(img_map);
        mapImage.setWhScale((float) mapImgWidth / mapImgHeight);
        mapImage.setHwScale((float) mapImgHeight / mapImgWidth);
        mapImage.setOriWidth(mapImgWidth);
        mapImage.setOriHeight(mapImgHeight);

        // Log.i("Map","WhScale:"+mapImage.getWhScale()+" HwScale:"+mapImage.getHwScale());

        float fw = ((float) mapImgWidth) / mapViewWidth;
        float fh = ((float) mapImgHeight) / mapViewHeight;

        if (fw >= fh) {

            mapImage.setWidth(mapViewWidth);
            mapImage.setHeight((int) (mapImgHeight / fw));

            mapImage.setLeft(0);
            mapImage.setTop((mapViewHeight - mapImage.getHeight()) / 2);

            mapImage.setMinTop(mapImage.getTop());
            mapImage.setMaxTop(mapImage.getTop());

            mapImage.setMinLeft(0);
            mapImage.setMaxLeft(0);

        } else {

            mapImage.setWidth((int) (mapImgWidth / fh));
            mapImage.setHeight(mapViewHeight);

            mapImage.setLeft((mapViewWidth - mapImage.getWidth()) / 2);
            mapImage.setTop(0);

            mapImage.setMinTop(0);
            mapImage.setMaxTop(0);

            mapImage.setMinLeft(mapImage.getLeft());
            mapImage.setMaxLeft(mapImage.getLeft());

        }
        mapImage.showNewState();
    }

    private void updateDeviceViewStation() {
        for (WaterMapObject waterMapObject : waterMapObjectList) {

            int left = (int) (mapImage.getLeft() + mapImage.getWidth() * waterMapObject.getLeftScale());
            int top = (int) (mapImage.getTop() + mapImage.getHeight() * waterMapObject.getTopScale());

            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(System_Dimen_Util.dip2px(activity, 40), ViewGroup.LayoutParams.WRAP_CONTENT);
            params.setMargins(left, top, 0, 0);

            waterMapObject.getWaterView().setLayoutParams(params);

        }

        for (DetectorMapObject detectorMapObject : detectorMapObjectList) {
            int left = (int) (mapImage.getLeft() + mapImage.getWidth() * detectorMapObject.getLeftScale());
            int top = (int) (mapImage.getTop() + mapImage.getHeight() * detectorMapObject.getTopScale());

            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            params.setMargins(left, top, 0, 0);

            detectorMapObject.getDetectorView().setLayoutParams(params);
        }
    }

    private List<WaterMapObject> waterMapObjectList = new ArrayList<>();
    private List<DetectorMapObject> detectorMapObjectList = new ArrayList<>();

    private void addDeviceView(float leftScale, float topScale, View view, int width) {

        int left = (int) (mapImage.getLeft() + mapImage.getWidth() * leftScale);
        int top = (int) (mapImage.getTop() + mapImage.getHeight() * topScale);

        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.setMargins(left, top, 0, 0);
        view.setLayoutParams(params);
        viewList.add(view);
        addView(view);
    }

    public void addWaterList(List<WaterListBean.Water> waterList) {
        if (waterList != null) {
            waterMapObjectList.clear();
            for (WaterListBean.Water water : waterList) {

                WaterMapObject waterMapObject = new WaterMapObject(activity, water);

                float leftScale = ((float) water.getPx() / mapImage.getOriWidth());
                float topScale = ((float) water.getPy() / mapImage.getOriHeight());

                waterMapObject.setLeftScale(leftScale);
                waterMapObject.setTopScale(topScale);

                addDeviceView(leftScale, topScale, waterMapObject.getWaterView(), System_Dimen_Util.dip2px(activity, 40));

                waterMapObjectList.add(waterMapObject);

            }

        }
    }

    public void allWatersOpenedSwitchs()
    {
        if (waterMapObjectList!=null)
        {
            for (WaterMapObject waterMapObject:waterMapObjectList)
            {
                waterMapObject.allSwitchsOpened();
            }
        }
    }

    public void allWaterClosedSwitchs()
    {
        if (waterMapObjectList!=null)
        {
            for (WaterMapObject waterMapObject:waterMapObjectList)
            {
                waterMapObject.allSwitchsClosed();
            }
        }
    }

    public void watersOpenedFailure(String waterIds,int waterLength)
    {
        if (waterMapObjectList!=null)
        {
            for (int i=0;i<waterMapObjectList.size();i++)
            {
                WaterMapObject waterMapObject=waterMapObjectList.get(i);
                waterMapObject.openSwitchsFailure(waterIds,waterLength);
            }
        }
    }

    public void addDetectorList(List<DetectorListBean.Detector> detectorList) {
        if (detectorList != null) {
            detectorMapObjectList.clear();
            for (DetectorListBean.Detector detector : detectorList) {
                DetectorMapObject detectorMapObject = new DetectorMapObject(activity, detector);

                float leftScale = ((float) detector.getPx() / mapImage.getOriWidth());
                float topScale = ((float) detector.getPy() / mapImage.getOriHeight());

                detectorMapObject.setLeftScale(leftScale);
                detectorMapObject.setTopScale(topScale);

                addDeviceView(leftScale, topScale, detectorMapObject.getDetectorView(), ViewGroup.LayoutParams.WRAP_CONTENT);

                detectorMapObjectList.add(detectorMapObject);
            }
        }
    }

    public void removeAllDeviceViews() {
        for (View view : viewList)
            removeView(view);
    }

    public void showHideDeviceName(boolean b)
    {
        for (WaterMapObject waterMapObject:waterMapObjectList)
            waterMapObject.showHideDeviceName(b);
        for (DetectorMapObject detectorMapObject:detectorMapObjectList)
            detectorMapObject.showHideDeviceName(b);

    }


}
